<?php
namespace wow\controller;

use \gnomephp\message\Message;
use \gnomephp\doctrine\Doctrine;
use \wow\model\forum as mf;
use \gnomephp\Configuration;

class Forum extends BaseController{

	public function __construct(){
		parent::__construct();
		$this->lang->load('forum');
	}

	/**
	 * Shows forums.
	 */
	public function index(){

		$this->view->assign('forums', mf\Forum::getAllForums($this->user ? $this->user->getGmLevel() : 0 ));
		$this->view->render('forum/index');
	}

	
	public function mod($type, $id, $action){
		if (!$this->isModerator()){
			Message::add(Message::ERROR, 'You have no access to this feature.');
			$this->redirect($this->view->url->linkTo('Forum','index'));
		}
		
		Doctrine::load();
		switch($type){
			case 'thread':
				$thread = mf\Thread::getThreadById($id);
				switch($action){
					case 'lock':
						
						$thread->setLocked(!$thread->isLocked());
						
						Doctrine::getEM()->persist($thread);
						
						Message::add(Message::SUCCESS,"Thread {$thread->getTitle()} locked / unlocked successfully.");
						break;
					case 'stick':
						$thread->setSticky(!$thread->isSticky());
						
						Doctrine::getEM()->persist($thread);
						
						Message::add(Message::SUCCESS,"Thread {$thread->getTitle()} sticked / unsticked successfully.");
						break;
					case 'delete':
						$thread->setDeleted(!$thread->isDeleted());
						
						Doctrine::getEM()->persist($thread);
						
						Message::add(Message::SUCCESS,"Thread {$thread->getTitle()} deleted / restored successfully.");
						break;
				}
				
				
				break;
			case 'post':
				$post = mf\Post::getPostById($id);
				
				switch($action){
					case 'delete':
						$post->setDeleted(!$post->isDeleted());
						
						Doctrine::getEM()->persist($post);
						
						Message::add(Message::SUCCESS,"Post #{$post->getID()} deleted successfully.");
						break;
				}
				break;
		}
		
		Doctrine::getEM()->flush();
		
		// Redirect back to referer.
		$this->redirect($_SERVER["HTTP_REFERER"]);
	}
	
	public function newThread($url){
		$forum = mf\Forum::getForumByUrl($url);
		if (!$this->user){
			Message::add(Message::ERROR, 'Please login or register to create new threads.');
			$this->redirect($this->view->url->linkTo('Forum','forumShow',array('title' => $forum->getUrl(), 'page' => 0 )));
		}
		
		
		
		$this->view->assignGlobal('allowTags', explode(',', \gnomephp\Configuration::get('forum','allowedPostTags')) );
		
		// Post new thread.
		$con = $this;
		$form = $this->view->createForm('threadForm', $this->view->url->linkTo('Forum','newThread', array('url' => $url)), 'post',
		function (\gnomephp\input\Input $input) use ($con, $forum){
			
			try{
				
				if (!$forum->canAddThread($con->user->getGmLevel())){
					throw new \gnomephp\input\DataFieldValidException(array("You are not allowed to create threads in this forum."));
				}
				
				$text = (string)$input->post->get('text',function($config){$config->set('HTML.Allowed', \gnomephp\Configuration::get('forum','allowedPostTags'));})->required()->validate('Post');
				$title = (string)$input->post->get('title',function($config){$config->set('HTML.Allowed', "");})->required()->validate('Title');
			
				if ($con->user){
					
					$postPrevent = Configuration::get('forum','post_prevent');
					if (!mf\Post::userCanCreateNewPost($con->user->getID(), $postPrevent['allow_posts'],$postPrevent['in_secs'])){
						throw new \gnomephp\input\DataFieldValidException(array(sprintf('You have to wait up to %s seconds before you can post again.', $postPrevent['in_secs'])));
					}
					$thread = new mf\Thread($title,$text,$con->user->getID(), $forum);
				
					
					Doctrine::load();
					Doctrine::getEM()->persist($thread);
					Doctrine::getEM()->flush();
					
					
					Message::add(Message::SUCCESS, "You have created a new thread.");
					$con->redirect($con->view->url->linkTo('Forum','thread',array('title' => $forum->getUrl(), 'id' => $thread->getID(), 'page' => 0 ) ));
				}
			}catch(\gnomephp\input\DataFieldValidException $e){
				Message::add(Message::ERROR, implode('<br />', $e->getErrors()));
			}
		
		}
		);
		$this->view->assign('threadForm', $form);
		
		
		
		$vFile = 'forum/new_thread';

		
		$this->view->assignGlobal('forum', $forum);
		
		$this->view->render($vFile);
	}

	/**
	 * Shows specific forum
	 */
	public function forumShow($url, $page = 0){

		$forum = mf\Forum::getForumByUrl($url);
		
		$vFile = 'forum/forum';


		$threads = $forum->getThreads($page);


		$this->view->assignGlobal('forum', $forum);

		$this->view->assign('pages', $forum->getPageArray());
		$this->view->assign('threads', $threads);
		$this->view->assign('curPage', $page);


		$this->view->render($vFile);

	}

	
	public function user($username, $id){
		// @todo Create user profile show of forum statistics for user.
	}
	
	
	public function thread($forumUrl, $id, $page = 0){
		$this->view->assignGlobal('allowTags', explode(',', \gnomephp\Configuration::get('forum','allowedPostTags')) );
		$forum = mf\Forum::getForumByUrl($forumUrl);

		$thread = $forum->getThread($id);
		
		$is_mod =  $this->isModerator();
		$this->view->assignGlobal('user_forum_mod', $is_mod );
		
		
		if ($this->user)mf\ThreadRead::read($this->user->getID(), $thread);
		
		// Post in thread.
		$con = $this;
		$form = $this->view->createForm('postForm', $this->view->url->linkTo('Forum','thread', array('title' => $forumUrl, 'id' => $id, 'page' => $page)), 'post',
		function (\gnomephp\input\Input $input) use ($con, $thread, $forum, $is_mod){
			try{
				if (!$forum->canAddThreadReply($con->user->getGmLevel())){
					throw new \gnomephp\input\DataFieldValidException(array("You are not allowed to create threads in this forum."));
				}
				
				// Check lock.
				if (!$thread->isLocked() || $is_mod){
				
				
				
					$text = (string)$input->post->get('text',function($config){$config->set('HTML.Allowed', \gnomephp\Configuration::get('forum','allowedPostTags'));})->required()->validate();
					$editID = (string)$input->post->get('editID')->validate();
					$postReplyId = (string)$input->post->get('postReplyId')->validate();
					
					if ($con->user){
						$postPrevent = Configuration::get('forum','post_prevent');
						if (!mf\Post::userCanCreateNewPost($con->user->getID(), $postPrevent['allow_posts'],$postPrevent['in_secs'])){
							throw new \gnomephp\input\DataFieldValidException(array(sprintf('You have to wait up to %s seconds before you can post again.', $postPrevent['in_secs'])));
						}
						Doctrine::load();
						if ($editID){
							$post = mf\Post::getPostById($editID);
							// Check privelegies.
							if (!$is_mod && !$con->user->getID() == $post->getAccount()->getID()){
								throw new \gnomephp\input\DataFieldValidException(array('Account missmatch for editing. Not allowed.'));
							}
							$post->setText($text);
							Doctrine::getEM()->persist($post);
						}else{
							$post = new mf\Post($con->user->getID(), $text, $forum, $thread);
							$thread->addPost($post);
							Doctrine::getEM()->persist($thread);
						}
						
						if ($postReplyId){
							$reply = mf\Post::getPostByIdAndThread($postReplyId, $thread->getID());
							if ($reply){
								$post->setParent($reply);
								Doctrine::getEM()->persist($post);
							}
						}
						
						
						
						
						Doctrine::getEM()->flush();
					
					
						Message::add(Message::SUCCESS, "Your post has been ".($editID ? 'edited' : 'added').". Thank you.");
					}
				}
			}catch(\gnomephp\input\DataFieldValidException $e){
				Message::add(Message::ERROR, implode('<br />', $e->getErrors()));
			}
		}
		);

		$this->view->assign('postForm', $form);

		$posts = $thread->getPosts($page);

		$this->view->assignGlobal('forum', $forum);
		$this->view->assignGlobal('thread', $thread);

		
		$this->view->assign('pages', $thread->getPageArray());
		$this->view->assign('posts', $posts);
		$this->view->assign('curPage', $page);

		
		
		
		
		$this->view->render('forum/thread');
	}
	
	protected function isModerator(){
		return ($this->user && $this->user->getGmLevel() > 0);
	}
}